package main

import (
	"fmt"
	"github.com/aphasia51/website/internal/repository"
	"github.com/aphasia51/website/internal/repository/dao"
	"github.com/aphasia51/website/internal/service"
	"github.com/aphasia51/website/internal/web"
	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
	"strings"
	"time"
)

func main() {
	db := initDb()
	server := initWebServer()

	user := initUser(db)
	accident := initAccident(db)
	chemical := initChemical(db)
	consumables := initConsumables(db)
	experimentalPersonnel := initExperimentPersonnel(db)
	wasteChemical := initWasteChemical(db)
	safetyEducation := initSafetyEducation(db)
	experiment := initExperiment(db)
	equipment := initEquipment(db)
	user.RegistryRoutes(server)
	accident.RegistryRoutes(server)
	chemical.RegistryRoutes(server)
	consumables.RegistryRoutes(server)
	experimentalPersonnel.RegistryRoutes(server)
	wasteChemical.RegistryRoutes(server)
	safetyEducation.RegistryRoutes(server)
	experiment.RegistryRoutes(server)
	equipment.RegistryRoutes(server)

	server.Run("127.0.0.1:8080")
}

func initWebServer() *gin.Engine {
	server := gin.Default()

	server.Use(func(ctx *gin.Context) {
		fmt.Println("first middleware")
	}, func(ctx *gin.Context) {
		fmt.Println("second middleware")
	})

	server.Use(cors.New(cors.Config{
		// 允许跨域访问的协议域名端口号
		//AllowOrigins: []string{"http://localhost:3000"},
		AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"},
		AllowHeaders: []string{"Origin", "Content-Length", "Content-Type", "Authorization"},
		// 是否允许带cookie之类的
		AllowCredentials: true,
		MaxAge:           12 * time.Hour,
		ExposeHeaders:    []string{"x-jwt-token"},
		AllowOriginFunc: func(origin string) bool {
			if strings.Contains(origin, "http://localhost") {
				return true
			}
			return strings.Contains(origin, "aphasia.top")
		},
	}))

	//login := &middleware.LoginMiddlewareBuilder{}
	////store := cookie.NewStore([]byte("secret"))
	//store, err := redis.NewStore(
	//	16,
	//	"tcp",
	//	"127.0.0.1:6379",
	//	"",
	//	[]byte("uQyn8y9gbnd7q4zkq2m73yw8tu9j5ixm"),
	//	[]byte("o6jdlo2cb9f9pb6h46fimllw481ldebi"),
	//)
	//if err != nil {
	//	panic(err)
	//}
	//server.Use(sessions.Sessions("ssid", store), login.CheckLogin())

	return server
}

func initUser(db *gorm.DB) *web.UserHandler {
	ud := dao.NewUserDap(db)
	repo := repository.NewUserRepository(ud)
	svc := service.NewUserService(repo)
	u := web.NewUserHandler(svc)
	return u
}

func initAccident(db *gorm.DB) *web.AccidentHandler {
	ad := dao.NewAccidentDap(db)
	repo := repository.NewAccidentRepository(ad)
	svc := service.NewAccidentService(repo)
	u := web.NewAccidentHandler(svc)
	return u
}

func initChemical(db *gorm.DB) *web.ChemicalHandler {
	cd := dao.NewChemicalDap(db)
	repo := repository.NewChemicalRepository(cd)
	svc := service.NewChemicalService(repo)
	c := web.NewChemicalHandler(svc)
	return c
}

func initConsumables(db *gorm.DB) *web.ConsumablesHandler {
	cd := dao.NewConsumablesDap(db)
	repo := repository.NewConsumablesRepository(cd)
	svc := service.NewConsumablesService(repo)
	c := web.NewConsumablesHandler(svc)
	return c
}

func initWasteChemical(db *gorm.DB) *web.WasteChemicalHandler {
	wd := dao.NewWasteChemicalDap(db)
	repo := repository.NewWasteChemicalRepository(wd)
	svc := service.NewWasteChemicalService(repo)
	w := web.NewWasteChemicalHandler(svc)
	return w
}

func initExperimentPersonnel(db *gorm.DB) *web.ExperimentalPersonnelHandler {
	ed := dao.NewExperimentalPersonnelDap(db)
	repo := repository.NewExperimentPersonnelRepository(ed)
	svc := service.NewExperimentalPersonnelService(repo)
	e := web.NewExperimentalPersonnelHandler(svc)
	return e
}

func initSafetyEducation(db *gorm.DB) *web.SafetyEducationHandler {
	sd := dao.NewSafetyEducationDap(db)
	repo := repository.NewSafetyEducationRepository(sd)
	svc := service.NewSafetyEducationService(repo)
	s := web.NewSafetyEducationHandler(svc)
	return s
}

func initExperiment(db *gorm.DB) *web.ExperimentHandler {
	e := dao.NewExperimentDap(db)
	repo := repository.NewExperimentRepository(e)
	svc := service.NewExperimentService(repo)
	s := web.NewExperimentHandler(svc)
	return s
}

func initEquipment(db *gorm.DB) *web.EquipmentHandler {
	e := dao.NewEquipmentDap(db)
	repo := repository.NewEquipmentRepository(e)
	svc := service.NewEquipmentService(repo)
	s := web.NewEquipmentHandler(svc)
	return s
}

func initDb() *gorm.DB {
	db, err := gorm.Open(mysql.Open("root:root@tcp(localhost:3306)/db"), &gorm.Config{
		// cancel s behind table name
		NamingStrategy: schema.NamingStrategy{SingularTable: true},
	})
	if err != nil {
		panic(err)
	}

	//err = dao.InitTable(db)
	//if err != nil {
	//	panic(err)
	//}

	return db
}
